package com.xbongbong.saas.model.impl;

import com.xbongbong.i18n.util.I18nMessageUtil;
import com.xbongbong.paas.constant.PaasConstant;
import com.xbongbong.paas.constant.TimeConstant;
import com.xbongbong.paas.domain.entity.StageLogEntity;
import com.xbongbong.paas.enums.StageTypeEnum;
import com.xbongbong.paas.toolbox.exception.XbbException;
import com.xbongbong.paas.toolbox.util.Arith;
import com.xbongbong.paas.toolbox.util.CollectionsUtil;
import com.xbongbong.paas.toolbox.util.DateTimeUtil;
import com.xbongbong.pro.constant.CommonConstant;
import com.xbongbong.saas.domain.dao.CustomerStageLogDao;
import com.xbongbong.saas.domain.entity.CustomerStageLogEntity;
import com.xbongbong.saas.domain.entity.ext.StageLogEntityExt;
import com.xbongbong.saas.model.CustomerStageLogModel;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import java.util.stream.Collectors;

/**
 * @author haibin.zhang
 * @version v1.0
 * @date 2019/3/10 16:43
 * @since v1.0
 */
@Service("customerStageLog")
public class CustomerStageLogModelImpl implements CustomerStageLogModel {

    @Resource
    private CustomerStageLogDao dao;

    @Override
    public Map<String, Double> getAverageStayTime(String corpid, Set<Long> customerIdIn, List<String> stageCodeIn) {
        Map<String, Object> param = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        param.put("corpid", corpid);
        param.put("del", 0);
        if (Objects.nonNull(customerIdIn)){
            param.put("dataIdIn", customerIdIn);
        }
        if (stageCodeIn.size() == 1){
            param.put("stageCode", stageCodeIn.get(0));
        }else {
            param.put("stageCodeIn", stageCodeIn);
        }
        List<StageLogEntityExt> stageLogList = dao.getAverageStayTime(param);

        //阶段code--平均停留时长
        Map<String, Double> dayMap = new HashMap<>(stageLogList.size());
        if (stageLogList.size() == 0) {
            return dayMap;
        }
        for (StageLogEntityExt entity : stageLogList) {
            String stageCode = entity.getStageCode();
            Double averageDay = entity.getAverageDay();
            if (stageCode == null || averageDay == null) {
                continue;
            }
            //保留一位小数
            averageDay = Arith.div(averageDay, 1, 1);
            dayMap.put(stageCode, averageDay);
        }
        return dayMap;
    }

    @Override
    public CustomerStageLogEntity getNowStageLog(Long customerId, String corpid, Long formId) {
        Map<String,Object> map = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        map.put("corpid",corpid);
        map.put("formId", formId);
        map.put("dataId",customerId);
        map.put("isNow",1);
        map.put("del",0);
        map.put("start",0);
        map.put("pageNum",1);
        List<CustomerStageLogEntity> customerStageLogEntityList = dao.findEntitys(map);
        if (customerStageLogEntityList.isEmpty()){
            return null;
        }else {
            return customerStageLogEntityList.get(0);
        }
    }

    @Override
    public String getAverageStayTime(String corpid, Long customerId, Long formId) throws XbbException {
        CustomerStageLogEntity nowLog = getNowStageLog(customerId, corpid, formId);
        if (nowLog == null){
            return null;
        }
        Long intoTime = nowLog.getIntoTime();
        intoTime = Objects.isNull(intoTime) ? 0L : intoTime;
        Long historyStayTime = nowLog.getHistoryStayTime();
        historyStayTime = Objects.isNull(historyStayTime) ? 0L : historyStayTime;

        double stayTimeInt = (double) (historyStayTime + DateTimeUtil.getInt() - intoTime);
        Double stayTimeDay = Arith.div(stayTimeInt,TimeConstant.SECONDS_PER_DAY,1);
        return stayTimeDay + I18nMessageUtil.getMessage(CommonConstant.DAY);
    }

    @Override
    public List<CustomerStageLogEntity> findEntitys(Map<String, Object> param) {
        return dao.findEntitys(param);
    }

    @Override
    public void save(CustomerStageLogEntity customerStageLogEntity) {
        if (customerStageLogEntity.getId() == null){
            dao.insert(customerStageLogEntity);
        }else {
            long now = DateTimeUtil.getInt();
            customerStageLogEntity.setUpdateTime(now);
            dao.update(customerStageLogEntity);
        }
    }

    @Override
    public void insertBatch(List<CustomerStageLogEntity> customerStageLogList) {
        if (CollectionsUtil.isNotEmpty(customerStageLogList)) {
            dao.insertBatch(customerStageLogList);
        }
    }

    @Override
    public Integer deleteByStageProcessIdAndDataIdIn(List<Long> dataIdIn, String corpid, Long formId, Long stageProcessId, Long stageId) {
        return dao.deleteByStageProcessIdAndDataIdIn(dataIdIn, corpid, formId, stageProcessId, stageId);
    }

    @Override
    public void deleteEntitys(Map<String, Object> searchParam) {
        dao.deleteEntitys(searchParam);
    }

    @Override
    public CustomerStageLogEntity getByKey(Long id, String corpid) {
        return dao.getByKey(id, corpid);
    }

    /**
     * 获取客户流失前的阶段
     *
     * @param corpid
     * @param customerIdIn
     */
    @Override
    public Map<Long, String> getCustomerLoseBeforeStage(String corpid, List<Long> customerIdIn, Map<String, String> stageCodeName) {
        Map<Long, String> customerIdAndBeforeStageNameMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<String,Object> map = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        map.put("corpid",corpid);
        map.put("dataIdIn",customerIdIn);
        map.put("isNow",1);
        map.put("stageType", StageTypeEnum.FAIL_STAGE.getType());
        map.put("del",0);
        List<CustomerStageLogEntity> customerStageLogEntityList = dao.findEntitys(map);
        if (!customerStageLogEntityList.isEmpty()){
            for(CustomerStageLogEntity entity : customerStageLogEntityList){
                String beforeStage = entity.getBeforeStageCode();
                String beforeStageName = stageCodeName.get(beforeStage) == null ? "--" : stageCodeName.get(beforeStage);
                customerIdAndBeforeStageNameMap.put(entity.getDataId(), beforeStageName);
            }
        }
        return customerIdAndBeforeStageNameMap;
    }

    /**
     * 获取客户流失时间
     *
     * @param corpid
     * @param customerIdIn
     */
    @Override
    public Map<Long, Long> getCustomerLoseTime(String corpid, List<Long> customerIdIn) {
        Map<Long, Long> customerIdAndLoseTimeMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        Map<String,Object> map = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        map.put("corpid",corpid);
        map.put("dataIdIn",customerIdIn);
        map.put("isNow",1);
        map.put("stageType", StageTypeEnum.FAIL_STAGE.getType());
        map.put("del",0);
        List<CustomerStageLogEntity> customerStageLogEntityList = dao.findEntitys(map);
        if (!customerStageLogEntityList.isEmpty()){
            for(CustomerStageLogEntity entity : customerStageLogEntityList){
                customerIdAndLoseTimeMap.put(entity.getDataId(), entity.getIntoTime());
            }
        }
        return customerIdAndLoseTimeMap;
    }

    @Override
    public void updateBatch(List<CustomerStageLogEntity> updateList, String corpid) throws XbbException {
        dao.updateBatch(updateList,corpid);
    }

    @Override
    public void updateBatch4Script(List<CustomerStageLogEntity> updateList) throws XbbException {
        dao.updateBatch4Script(updateList);
    }

    /**
     * 获取当前流失客户阶段日志
     */
    @Override
    public List<Long> getLoseCustomerList(Map<String,Object> param) throws XbbException {
        List<CustomerStageLogEntity> stageLogList = dao.findEntitys(param);
        if (CollectionsUtil.isEmpty(stageLogList)) {
            List<Long> dataList = new ArrayList<>();
            dataList.add(-1L);
            return dataList;
        } else {
            return stageLogList.stream().map(CustomerStageLogEntity::getDataId).distinct().collect(Collectors.toList());
        }
    }

    /**
     * 获取当前流失客户阶段分组统计
     *
     */
    @Override
    public Map<String, Integer> getStageStatistic(Long formId, String corpid, List<Long> customerIdIn) throws XbbException {
        Map<String,Object> map = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        map.put("corpid",corpid);
        map.put("isNow",1);
        map.put("formId",formId);
        map.put("stageType", StageTypeEnum.FAIL_STAGE.getType());
        if(customerIdIn != null){
            map.put("dataIdIn",customerIdIn);
        }
        map.put("del",0);
        List<Map<String, Object>> customerStageLogMap = dao.getStageStatistic(map);
        Map<String, Integer> tempMap = new HashMap<>(PaasConstant.DEFAULT_INITIAL_CAPACITY);
        if (customerStageLogMap != null && customerStageLogMap.size() > 0) {
            for (Map<String, Object> customerMap : customerStageLogMap) {
                String beforeStageCode = String.valueOf(customerMap.get("beforeStageCode"));
                Integer beforeStageCount = Integer.valueOf(customerMap.get("beforeStageCount").toString());
                tempMap.put(beforeStageCode, beforeStageCount);
            }
        }
        return tempMap;
    }

    @Override
    public List<CustomerStageLogEntity> findStageLogWithoutStage() {
        return dao.findStageLogWithoutStage();
    }

    @Override
    public Integer deleteBatch(List<StageLogEntity> stageLogEntityList, String corpid) {
        return dao.deleteBatch(stageLogEntityList, corpid);
    }

    @Override
    public Integer getEntitysCount(Map<String, Object> param) {
        return dao.getEntitysCount(param);
    }

    @Override
    public CustomerStageLogEntity getIsNowStage(String corpid, Long formId, Long dataId) {
        return dao.getIsNowStage(corpid, formId, dataId);
    }

    @Override
    public Long getAvgStayTime(String corpid, Long stageProcessId, Long stageId) {
        return dao.getAvgStayTime(corpid, stageProcessId, stageId);
    }

    @Override
    public List<Long> findUsedStageProcessId(String corpid, Long formId, List<Long> stageProcessIdIn) {
        return dao.findUsedStageProcessId(corpid, formId, stageProcessIdIn);
    }
}
